<template>
  <div class="uploadByH5">
    <h2>This is an up load By H5's page</h2>
    <div style="position:relative">
       <div class="btnBox">
        <div class="hoverbtn"><label class="btn" for="avatar">选择图片(PNG, JPG)</label></div>
        <div class="hoverbtn"><label class="btn" @click="submit">上传图片</label></div>
       </div>
      	<input th:value="文件上传" style="opacity: 1" type="file" id="avatar"  name="avatar" @change="filesChange" accept="image/png, image/jpeg">
    <div slot="tip" class="upload__tip">
        只能上传jpg/png文件，且不超过500000000000kb
      </div>
      <div style="font-weight:700;" v-show="imgSrc!=''">上传图片后的图片显示</div>
    <img style="max-height:400px;max-width:400px;margin:0 auto;" v-show="imgSrc!=''" :src="imgSrc" alt="">
    </div>
    <h3 v-show="beforePreview_title==''">图片预览</h3>
    <div class="preview">
      <!--createObjectURL的预览  -->
    <div class="previewBycreateObjectURL">
    <div v-show="beforePreview_title==''">{{beforePreview_title!='' ? beforePreview_title : imgPreview1_title}}</div>
    <img v-show="beforePreview_title!=''" src="" alt="">
    <img v-show="beforePreview_title==''" :src="imgPreview1" alt="">
    </div>
    <!--createObjectURL的预览  -->
    <!-- base64的预览 -->
    <div class="previewByBase64">
    <div v-show="beforePreview_title==''">{{beforePreview_title!='' ? beforePreview_title : imgPreview2_title}}</div>
    <img v-show="beforePreview_title!=''" src="" alt="">
    <img v-show="beforePreview_title==''" :src="imgPreview2" alt="">
    </div>
    <!-- base64的预览 -->
    </div>
  </div>
</template>
<script>
import axios from "axios"; //axios用于网络请求
export default{
		name:'uploadByH5',
		data(){
			return{
      imgPreview1:'',//图片预览 URL.createObjectURL生成对象的预览地址
      imgPreview2:'',//base64实现图片的预览
      beforePreview_title:'上传图片吧,可以生成预览',
      imgPreview1_title:'URL.createObjectURL生成图片对象地址的预览',//预览标题
      imgPreview2_title:'Base64生成的图片的预览',//预览标题
      token: "", //token 上传凭证
      uploadArea: "https://upload-z2.qiniup.com", //此处为七牛云华南区的空间地址
      domain:'http://hmytest.humianyuan.cn/',//我bucket绑定的域名，就是图片上传后的访问域名
      fileData: "",//文件数据流，用于保存上传七牛云
      fileName:'',//文件名，用于上传后的命名方式,
      imgSrc:'',//用于保存上传后的图片地址
			 }
		},
    methods: {
      // 1.用于捕获图片改变且向后端索要token 获取token前的操作
      filesChange(e) {
        this.imgSrc = ''//初始化
        // 1.1变量赋值
        this.fileData = e.target.files[0];//文件对象 为blob即大型二进制类型
        this.fileName = "hmytest_"+Date.now()+e.target.files[0].name;//文件重命名名
        console.log("打印文件对象:",e.target.files[0]);
        console.log("打印文件对象:",this.fileData);
        // 注意此处的图片预览我开始的时候有疑惑，为什么不直接获取用户点击的相对地址，比如用户点击了E://myImage/3.jpg
        //然后把相对地址进行赋值给img的src属性呢？我们平常使用也是直接获取图片的地址赋值给src，然后图片就可以显示了，
        // 但是我在思否提问，并且后来在MDN文档明确看到下面这段话，总结为出于安全原因，web不能直接读取用户电脑的数据，包括相对地址
        // 所以此处只能通过鼠标点击对象获取file，即获取点击的图片，然后转成base64，在进行赋值给src实现在线预览；或者使用URL.createObjectURL(),然后传入文件对象或者blob类型,并且文件对象本身就是一种特殊的blob类型，它是基于blob类型的;文件接口是html5体系建立起来后给的一种前端上传下载的解决方案。
        // 此处附上我当时在思否的提问，关于为什么不直接图片相对地址实现在线预览的回答：
        // 这个是MDN文档的明确规定,你打开这个地址,然后下拉到注意事项【大概下拉0.6个window窗口高度可以看到】，里面有写：https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/file
        console.log('***********************************')
        // 1.2图片预览实现
        // 预览图片的实现 第一种方法 URL.createObjectURL 生成一个本页面的url地址符
        this.imgPreview1 = window.URL.createObjectURL(this.fileData)//传入文件对象,即一个blob大型二进制类型，实现预览
        console.log("图片的URL.createObjectURL生成的预览地址:",this.imgPreview1);
        // 预览图片的实现 二种方法 readAsDataURL()生成base64
        var reader = new FileReader();//读取文件
        reader.onload = (e) => {//文件读取完毕会触发这里的回调，详细用法看MDN
          this.imgPreview2 = reader.result//读取结果
          console.log('***********************************')
          console.log("图片的base64的二进制流：",this.imgPreview2)
          this.beforePreview_title = ''//此处与本demo无关,只是为了控制样式
        }
        reader.readAsDataURL(this.fileData);//以base64读取文件对象 细节同样MDN有 此处读取完毕会触发上面的onload，原理和window.onload()一样
         
        // 1.3获取服务器token
      axios.get("/api_hu66/upload_byfront/token").then((res) => {
          console.log("*********************************")
          console.log("接收到后台传来的token：",res.data.token);
          this.token = res.data.token;//赋值后台传来的token
        })
      },
      // 2.获取token后开始上传 获取token后的操作
      submit(){
        //成功预览的情况下，才上传图片
        if(this.imgPreview1!=''&&this.imgPreview2!=''){
            // 2.1初始化表单数据,并追加表单数据
          const formdata = new FormData();
          formdata.append("file", this.fileData);//向表单追加文件数据 的键值对
          formdata.append("token", this.token);//向表单追加token 的键值对
          formdata.append("key", this.fileName);//向表单追加文件名称 的键值对
          
          // 2.2发送七牛云 参数分别是 1.七牛云华南区的地址【你开辟bucket空间的所在区域的域名】 2.表单数据【即我们需要上传的文件数据】 3.设置header请求头的媒体类型为，用来通知无需对此数据编码再发送，因为普通表单数据传输的时候会进行编码，但是此处如果是二进制数据的话则无需编码
          axios.post(this.uploadArea,formdata, {
              headers: { "Content-Type": "multipart/form-data" },
            }).then((res) => {
              console.log("*********************************")
              console.log("上传服务器后传回的响应数据：",res)
              console.log("图片访问地址:",this.domain+this.fileName);
              this.imgSrc = this.domain+this.fileName;//生成图片地址
              window.URL.revokeObjectURL(this.fileData);//卸载预览
              this. beforePreview_title = '上传图片吧,可以生成预览'//恢复初始化
              this.imgPreview1 = '';//恢复初始化
              this.imgPreview2 = ''//恢复初始化
              })
        }else{
          this.$message('已完成上传!');
        }
      }
    },
	}
</script>
<style>
.uploadByH5 {
  z-index: 2;
  padding-top: 100px;
  position: relative;
  width: 300px;
  margin: 0 auto;
}	
.upload__tip{
  margin:15px auto;
}
.preview{
  width: 100%;
  display: flex;
  justify-content: center;
  color: brown;
  font-weight: 700;
}
.previewBycreateObjectURL{
  margin-right: 50px;
  margin-bottom:100px ;
}
.btnBox{
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 100vw;
  height: 50px;
  cursor: pointer;
}
.hoverbtn{
  display: inline-block;
  background-color: burlywood;
  cursor: pointer;
	padding: 5px 10px;
  height: 200px;
	border-radius: 5px;
	border: 1px ridge black;
	margin-right: 20px;
	height: auto;
  transition: all 0.3s;
}
.hoverbtn:hover{
  color: #ffffff;
  display: inline-block;
  transform: scale(1.1);
}
</style>
